package com.rabbits.ui.dialog.custom;

import android.app.Activity;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.Gravity;
import android.widget.LinearLayout;

import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactRootView;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableNativeMap;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

public class RNJsCustomDialogModule extends ReactContextBaseJavaModule {

    private final ReactApplicationContext reactContext;
    private final Object object = new Object();
    private JsCustomDialog jsCustomDialog = null;

    public RNJsCustomDialogModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext = reactContext;
    }

    @Override
    public String getName() {
        return "RNJsCustomDialog";
    }

    /**
     * 显示对话框
     *
     * @param rnName     js填充内容模块名称
     * @param props      js填充内容模块属性
     * @param cancelable 对话框是否可以外部关闭
     * @param promise    cancelable=true时，取消回调
     */
    @ReactMethod
    public void show(String rnName, ReadableMap props, boolean cancelable, final Promise promise) {
        showDialog(rnName, props, cancelable, new JsCustomDialog.OnCancelListener() {
            @Override
            public void onCancel() {
                promise.resolve("cancel");
            }
        });
    }


    @ReactMethod
    public void dismiss() {
        dismissDialog();
    }


    private void showDialog(final String rnName, final ReadableMap props,
                            final boolean cancelable, final JsCustomDialog.OnCancelListener listener) {
        dismissDialog();
        final Activity act = getCurrentActivity();
        if (act != null && !act.isFinishing()) {
            act.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (jsCustomDialog == null) {
                        synchronized (object) {
                            if (jsCustomDialog == null) {
                                ReactRootView reactRootView = getReactRootView(rnName, props);
                                jsCustomDialog = new JsCustomDialog.Builder()
                                        .setReactView(reactRootView)
                                        .cancelable(cancelable).onCancel(listener).build(act);
                            }
                        }
                    }
                    if (jsCustomDialog != null) {
                        jsCustomDialog.show();
                    }
                }
            });
        }
    }

    private ReactRootView getReactRootView(String rnName, ReadableMap props) {
        ReactRootView reactRootView = null;
        try {
            reactRootView = new ReactRootView(getReactApplicationContext());
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            params.gravity = Gravity.CENTER;
            reactRootView.setLayoutParams(params);
            ReactApplication reactApplication = (ReactApplication) (getCurrentActivity().getApplication());
            ReactNativeHost reactNativeHost = reactApplication.getReactNativeHost();
            Bundle bundle = new Bundle();
            if (props != null) {
                ReadableNativeMap tempMap = (ReadableNativeMap) props;
                HashMap<String, Object> dataMap = tempMap.toHashMap();
                for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
                    if (entry.getValue() instanceof Serializable) {
                        bundle.putSerializable(entry.getKey(), (Serializable) entry.getValue());
                    } else if (entry.getValue() instanceof Parcelable) {
                        bundle.putParcelable(entry.getKey(), (Parcelable) entry.getValue());
                    } else {
                        Log.e(getName(), "Can not resolve with: " + entry.getKey() + " ,witch can not be serializable and abandon it.");
                    }
                }
            }
            reactRootView.startReactApplication(reactNativeHost.getReactInstanceManager(), rnName, bundle);
        } catch (Exception e) {
            e.printStackTrace();
            reactRootView = null;
        }
        return reactRootView;
    }

    private void dismissDialog() {
        if (jsCustomDialog != null) {
            try {
                synchronized (object) {
                    if (jsCustomDialog != null) {
                        jsCustomDialog.dismiss();
                    }
                    jsCustomDialog = null;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
